home *** CD-ROM | disk | FTP | other *** search
- {
- XDR> I'm currently developing an application that I would gladly spread in
- XDR> protected mode... But could someone explain to me what can I NOT do in
- XDR> DPMI pascal
-
- This is actually explained quite clearly in Ch. 17 of the BP7 Language Guide.
-
- The main difference is that memory is no longer yours to do with as you
- please; you can only "touch" memory that has been allocated to your program.
- This is where the "protected" in "protected mode" stems from.
-
- The following is a rather simplified view of things, but it does illustrate
- the general priciple:
-
- In pmode a pointer such as ptr($B800, 0) does NOT point to memory location
- $B800:0000. The segment part (called the "selector" in pmode), $B800,
- is treated as an index into a system maintained table, which *does* contain
- the actual physical memory location (called the "base"), and the number of
- bytes allocated to that base (called the "limit"). This table is unavailable
- to your program.
- At the start of your program, all entries in this table are marked "not in
- use" and therefore illegal.
- During program execution, whenever you attempt to read or write Mem[S:O],
- the CPU checks (in that table) to see if S is a legal index (i.e., if S is
- a valid base), and if so, whether O is within the limit of that base.
- If at least one of these checks fail, the memory access is invalid, and you
- will be presented with run time error 216 a.k.a. the dreaded General
- Protection Failure (GPF) a.k.a. Exception $0D.
-
- XDR> Ag: I can no more acces the screen at an Obsolute $b800:000 but at
- XDR> absolute Segb800:000, why?
-
- Btw: ABSOLUTE SegB800:0 won't compile.
- Use "mem[SegB800:0]" instead, or use a pointer, like so:
-
- VAR VidMemStart: pointer;
- BEGIN VidMemStart:=ptr(SegB800, 0) END;
-
- and manipulate video memory using VidMemStart^.
-
- The reason should now be clear: $B800 is almost certainly *not* a valid
- selector. Since no one has asked the DPMI server to associate selector $B800
- with a physical memory location, it is illegal.
- You *can* use SegB800, as your program startup code asks the DPMI server to
- associate SegB800 with video memory.
-
- You should not pass pmode pointers to real mode routines nor the other way
- around (they are invalid in the "receiving" mode).
- It can be done, but you'll need the cooperation of the DPMI server.
- Find a DPMI unit (I can't post mine, as it is commercial). Below you'll
- find such a unit - I've never used it, so no guarantees.
-
- Notes: - if you attempt to write to code segments, or read from invalid
- pointers, a GPF will result.
- - if you attempt to read an invalid stack element, you will receive
- an Exception $0C (Stack Fault), which BP will convert to run time
- error 202.
- - Exception 6 (Invalid Opcode) is not related to memory accesses.
- It means the CPU has received a couple of bytes which it cannot
- interpret as a valid instruction.
- - prior to distribution, be sure to read file DPMIUSER.DOC.
- You can find that file in archive DOC.ZIP on your BP7 distribution
- disks.
-
- The above three exceptions are likely the only ones you'll see.
-
- Happy programming,
-
- Peter. }
-
- ===== Start of includefile FDEFINE.DEF =====
-
- { Include file FDEFINE.DEF - general include file for the unit systems
- conditional defines }
-
- (***************************************************************************
-
- RELEASE 1.04 - as contained in the file PRUS100.LZH
- by Orazio Czerwenka, 2:2450/540.55, GERMANY
-
- --------------------------------------------
- organized for Fido's PASCAL related echoes
- --------------------------------------------
-
- 06/21/1994 to --/--/---- by Orazio Czerwenka, 2:2450/540.55, GERMANY
-
- ***************************************************************************)
-
- { ==========================================================================
- WHICH VERSION OF TURBO PASCAL DO YOU COMPILE WITH ?
- THE DEFAULT IS TURBO PASCAL 6.0x !
- ========================================================================== }
-
- { The following conditional defines do not yet have any effect, ... }
-
- {.$define ver30} { Turbo Pascal 3.0x }
- {.$define ver40} { Turbo Pascal 4.0x }
- {.$define ver50} { Turbo Pascal 5.0x }
- {.$define ver55} { Turbo Pascal 5.5x }
- {$define ver60} { Turbo Pascal 6.0x }
- {.$define ver70} { Turbo/Borland Pascal 7.0x }
-
- { ... these commenting lines will be deleted once that should be changed. }
-
-
- { ==========================================================================
- WHAT LANGUAGE DO YOU WANT YOUR PROGRAMS TO DISPLAY MESSAGES IN BY DEFAULT?
- ========================================================================== }
-
- {$define English}
- {.$define German}
-
-
- { ==========================================================================
- ACTIVATE THE FOLLOWING DISABLED COMPILER DIRECTIVE IF YOU WANT TO BE ABLE
- TO USE THE UNIT SYSTEM FROM WITHIN OVERLAYS !
- ========================================================================== }
-
- {.$O+} { This tells your compiler - if activated - to produce a unit
- that will be allowed to be used from within overlays. }
-
- {$IFOPT O+}
- {$DEFINE Overlays} { easier to read }
- {$ENDIF}
-
- { ==========================================================================
- WHAT KIND OF PROCESSOR ARE YOU COMPILING FOR ? SOME CPU DEPENDEND DEFINES.
- ========================================================================== }
-
- (* Some of the units use inline assembler designed to work on machines
- with at least 80286 processor, so generally you can tell your compiler
- to produce 80286 code anyway.
- *)
-
- {$G+} { This tells - if activated - your compiler to produce 80286
- code. }
-
- (* In addition you might want to specify one of the following higher
- processors, if you want your programmes ONLY to run on THESE and
- higher machines.
- *)
-
- { The following conditional defines do not yet have any effect, ... }
-
- {.$define cpu386} { Use specific code for 80386 machines }
- {.$define cpu486} { Use specific code for 80486 machines }
-
- { ... these commenting lines will be deleted once that should be changed. }
-
- { -------------------------------------------------------------------------- }
-
- (* Define one of the following CRT replacements (or CRT) for use by the
- units FTMODE and FSPEAKER, depending on what you've got.
- If you don't have a replacement, take the CRT, it is a bit slower but
- it should work as well.
- -----------------------------------------------------------------------
- NOTICE THAT THE UNIT FCRT SHOULD ALSO BE INCLUDED IN THIS FILE PACKAGE!
- -----------------------------------------------------------------------
- Note that at least one of those units shoul be defined to be used !
- By default this should be the unit FCRT.
-
- In case you should also want to use TP CRT's screen handling related
- functions in addition to the routines provided by FCONDRV and FCRT
- you probably will have to define the usage of TP's CRT here.
- By default the usage of TP's CRT is *NOT* defined in order to avoid
- smaller drawbacks in speed and unnecessarilly 'blown up' code.
- *)
-
- {$define FCRT}
- {.$define CRT}
- {.$define CRT2}
-
-
-
- { -------------------------------------------------------------------------- }
-
- (* The following conditional define will specify wether the unit(s) FTMODE
- will use the BIOS for the 80x25 mode or try programming it by hand. You
- should leave it inactivated, since who would want to force the user to
- use 80x25 ? I (MM) implemented it, since on my system, mode 3 corresponds
- to 90x28 through a TSR, and a small program would have helped here :-)
- Note that forcing will only take place if FTMODE's SetVideoMode(3) does
- not result in an 80 column mode.
- *)
-
- {.$define UseBIOS}
-
-
-
- { -------------------------------------------------------------------------- }
-
- ===== End of includefile FDEFINE.DEF =====
-
- ===== Start of unit FDPMI =====
-
- Unit FDPMI; { routines for DOS/DPMI communication }
- (***************************************************************************
-
- RELEASE 1.00 - as contained in the file PRUS100.LZH
- by Max Maischein, 2:244/1106.17, GERMANY
-
- --------------------------------------------
- organized for Fido's PASCAL related echoes
- --------------------------------------------
-
- 06/15/1994 to --/--/---- by Max Maischein, 2:244/1106.17, GERMANY
-
- As far as third party copyrights are not violated this
- source code is hereby placed to the public domain. Use
- it whatever way you want, but use AT YOUR OWN RISK.
-
- In case you should modify the source rather send your
- modifications to the unit's current organizer (see above for
- NM address) than to spread it on your own. This will help to
- keep the unit updated and grant a certain standard to all
- other users as well.
-
- The unit is currently still under work. So it might greatly
- benefit of your participation.
-
- Those who contributed to the following piece of source,
- listed in alphabethical order:
- ================================================================
- Jochen Magnus (SEGDEMO.PAS), Max Maischein (collecting,
- documenting, testing etc.), Raphael Vanney (program CHARSET
- .PAS)
- ================================================================
- YOUR NAME WILL APPEAR HERE IF YOU CONTRIBUTE USEFUL SOURCE.
-
- ***************************************************************************)
-
- {$I FDEFINE.DEF}
-
- Interface
-
- Type TRealModeRegs =
- Record
- Case Integer Of
- 0: ( EDI, ESI, EBP, EXX, EBX, EDX, ECX, EAX: Longint;
- Flags, ES, DS, FS, GS, IP, CS, SP, SS: Word) ;
- 1: ( DI,DIH, SI, SIH, BP, BPH, XX, XXH: Word;
- Case Integer of
- 0: (BX, BXH, DX, DXH, CX, CXH, AX, AXH: Word);
- 1: (BL, BH, BLH, BHH, DL, DH, DLH, DHH,
- CL, CH, CLH, CHH, AL, AH, ALH, AHH: Byte));
- End;
- (* Use these and RealModeInt() instead of Registers and Intr() under DPMI *)
-
- Type TLongRec = Record
- Case Byte of
- 0 : ( L : LongInt );
- 1 : ( wLo : Word;
- wHi : Word; );
- 2 : ( iLo : Integer;
- iHi : Integer );
- End;
-
- Function RealModeInt( IntNo : Byte; Var RealRegs : TRealModeRegs) : Boolean;
- (* Replacement for Intr(), returns False on error *)
-
- Function NewSelector( Base, Limit : Longint) : Word;
- (* Returns a new selector for the range [Base - (Base+Limit)] *)
- (* Base is the linear address of the memory location you want to use *)
- (* You must free this selector after use with FreeSelector() *)
-
- Function AllocateLowMem( Size : Word; var PMPointer : Pointer ) : Word;
- (* Allocates some memory in the first MB *)
- (* Returns a pointer to it and a segment to pass to the real mode routine *)
-
- Procedure FreeLowMem(Var PMPointer : Pointer );
- (* Frees memory allocated with AllocateLowMem() *)
-
- Implementation
- Uses WinAPI;
-
- Function RealModeInt( IntNo : Byte; Var RealRegs : TRealModeRegs) : Boolean;
- Assembler;
- { This function switches to real mode and issues the specified interrupt,
- after filling the registers with values stored in RealRegs.
- If SS/SP as specified in RealRegs are Nil, the DPMI server provides a
- small stack. For more discution of this, see Ralf Brown's INTERxx.ZIP }
- Asm
- mov ax, 0300h { DPMI function "simulate real
- mode int" }
- mov bl, [IntNo]
- xor bh, bh { 0 as requested by DPMI v1.0
- } xor cx, cx { bytes to copy onto "remote"
- stack }
- les di, [RealRegs]
- int 31h { Returns CF set on error }
- mov ax, 1 { assume everything went OK }
- sbb ax, 0 { if carry set, decrement ax }
- { to signal an error }
- End;
-
- Function NewSelector(Base,Limit:longint) : Word;
- Var Sel : Word;
- Begin
- Sel := AllocSelector(0);
- If (sel<>0) and (setSelectorBase(sel,base)=sel) and (setSelectorLimit(sel,
- limit)=0)
- then newSelector:=sel
- else newSelector:=0;
- End;
-
- Function AllocateLowMem( Size : Word; var PMPointer : Pointer ) : Word;
- { This procedure allocates memory in the first megabyte, and returns two
- ways of accessing it : a pointer valid in protected mode, and the
- segment part of a pointer valid in real mode ; offset part is always 0 }
-
- Var Adr : LongInt ;
- Begin
- Adr:=GlobalDOSAlloc(Size) ;
- If Adr=0 then RunError( 0 );
- PMPointer := Ptr( TLongRec(Adr).wLo, 0);
- AllocateLowMem := TLongRec(Adr).wHi;
- End ;
-
- Procedure FreeLowMem(Var PMPointer : Pointer ) ;
- { Frees memory allocated with AllocateLowMem }
- Begin
- GlobalDOSFree(Seg( PMPointer^ ));
- PMPointer := nil;
- End ;
- {$IFnDEF DPMI}
- {$IFnDEF Windows}
- You are compiling WHAT ??
- {$ENDIF}
- {$ENDIF}
- End.
-
- ===== End of unit FDPMI =====